import {languages} from 'monaco-editor/esm/vs/editor/editor.api';
import {
	setupLanguageFeatures, LanguageIdEnum, EntityContextType
} from 'monaco-sql-languages';
import dataSourceApi from '@/api/datasource/dataSourceApi'

export const currentInfo = {
	id: null
}
//
// label: name,
// 	kind: monaco.languages.CompletionItemKind.Field,
// 	insertText: name

const completionService = async function (
	model,
	_position,
	_completionContext,
	suggestions
) {

	if (!suggestions) {
		return [];
	}
	const languageId = model.getLanguageId();
	// const haveCatalog = haveCatalogSQLType(languageId);
	// const getDBOrSchema = namedSchemaSQLType(languageId) ? querySchemaList : queryCatalogList;

	const {keywords, syntax} = suggestions;

	const keywordsCompletionItems = keywords.map((kw) => ({
		label: kw,
		kind: languages.CompletionItemKind.Keyword,
		detail: '关键字',
		sortText: '2' + kw
	}));

	let syntaxCompletionItems = [];

	/** 是否已经存在 catalog 补全项 */
	let existCatalogCompletions = false;
	/** 是否已经存在 database 补全项 tmpDatabase */
	let existDatabaseCompletions = false;
	/** 是否已经存在 database 补全项 */
	let existDatabaseInCatCompletions = false;
	/** 是否已经存在 table 补全项 tmpTable */
	let existTableCompletions = false;
	/** 是否已经存在 tableInDb 补全项 （cat.db.table） */
	let existTableInDbCompletions = false;
	/** 是否已经存在 view 补全项 tmpDb */
	let existViewCompletions = false;
	/** 是否已经存在 viewInDb 补全项  */
	let existViewInDbCompletions = false;

	/** 是否已经存在 字段 补全项  */
	let existColumnsInDbCompletions = false;

	for (let i = 0; i < syntax.length; i++) {
		const {syntaxContextType, wordRanges} = syntax[i];

		// e.g. words -> ['cat', '.', 'database', '.', 'table']
		const words = wordRanges.map((wr) => wr.text);
		const wordCount = words.length;

		if (
			syntaxContextType === EntityContextType.CATALOG ||
			syntaxContextType === EntityContextType.DATABASE_CREATE
		) {
			if (!existCatalogCompletions && wordCount <= 1) {
				syntaxCompletionItems = syntaxCompletionItems.concat(await queryCatalogList());
				existCatalogCompletions = true;
			}
		}

		if (
			syntaxContextType === EntityContextType.DATABASE ||
			syntaxContextType === EntityContextType.TABLE_CREATE ||
			syntaxContextType === EntityContextType.VIEW_CREATE
		) {
			if (!existCatalogCompletions && wordCount <= 1) {
				syntaxCompletionItems = syntaxCompletionItems.concat(await queryCatalogList());
				existCatalogCompletions = true;
			}

			if (!existDatabaseCompletions && wordCount <= 1) {
				syntaxCompletionItems = syntaxCompletionItems.concat(
					await querySchemaList()
				);
				existDatabaseCompletions = true;
			}
			if (!existDatabaseInCatCompletions && wordCount >= 2 && wordCount <= 3) {
				syntaxCompletionItems = syntaxCompletionItems.concat(
					await querySchemaList(words[0])
				);
				existDatabaseInCatCompletions = true;
			}
		}

		if (syntaxContextType === EntityContextType.TABLE) {
			if (wordCount <= 1) {
				if (!existCatalogCompletions) {
					const ctas = await queryCatalogList();
					syntaxCompletionItems = syntaxCompletionItems.concat(ctas);
					existCatalogCompletions = true;
				}

				if (!existDatabaseCompletions) {
					syntaxCompletionItems = syntaxCompletionItems.concat(
						await querySchemaList()
					);
					existDatabaseCompletions = true;
				}

				if (!existTableCompletions) {
					syntaxCompletionItems = syntaxCompletionItems.concat(
						await queryTableList()
					);
					existTableCompletions = true;
				}
			} else if (wordCount >= 2 && wordCount <= 3) {
				if (!existDatabaseInCatCompletions) {
					syntaxCompletionItems = syntaxCompletionItems.concat(
						await querySchemaList(words[0])
					);
					existDatabaseInCatCompletions = true;
				}

				if (!existTableInDbCompletions) {
					syntaxCompletionItems = syntaxCompletionItems.concat(
						await queryTableList(words[0])
					);
					existTableInDbCompletions = true;
				}
			} else if (wordCount >= 4 && wordCount <= 5) {
				if (!existTableInDbCompletions) {
					syntaxCompletionItems = syntaxCompletionItems.concat(
						await queryTableList(words[0], words[2])
					);
					existTableInDbCompletions = true;
				}
			}
		}

		if (syntaxContextType === EntityContextType.VIEW) {
			if (wordCount <= 1) {
				if (!existCatalogCompletions) {
					syntaxCompletionItems = syntaxCompletionItems.concat(
						await queryCatalogList()
					);
					existCatalogCompletions = true;
				}

				if (!existDatabaseCompletions) {
					syntaxCompletionItems = syntaxCompletionItems.concat(
						await querySchemaList()
					);
					existDatabaseCompletions = true;
				}

				if (!existViewCompletions) {
					// syntaxCompletionItems = syntaxCompletionItems.concat(
					// 	await getViews(languageId)
					// );
					existViewCompletions = true;
				}
			} else if (wordCount >= 2 && wordCount <= 3) {
				if (!existDatabaseInCatCompletions) {
					syntaxCompletionItems = syntaxCompletionItems.concat(
						await querySchemaList(words[0])
					);
					existDatabaseInCatCompletions = true;
				}

				if (!existViewInDbCompletions) {
					// syntaxCompletionItems = syntaxCompletionItems.concat(
					// 	await getViews( undefined, words[0])
					// );
					existViewInDbCompletions = true;
				}
			} else if (wordCount >= 4 && wordCount <= 5) {
				if (!existViewInDbCompletions) {
					// syntaxCompletionItems = syntaxCompletionItems.concat(
					// 	await getViews(words[0], words[2])
					// );
					existViewInDbCompletions = true;
				}
			}
		}

		let suggestions = []
		const {lineNumber, column} = _position
		const textBeforePointer = model.getValueInRange({
			startLineNumber: lineNumber,
			startColumn: 0,
			endLineNumber: lineNumber,
			endColumn: column
		})
		const wrodsKey = textBeforePointer.trim().split(/\s+/)
		const lastWord = wrodsKey[wrodsKey.length - 2]


		if (syntaxContextType === EntityContextType.COLUMN) {
			// debugger
			let sp = lastWord.split(".");
			let tableName = null;
			let catalogName = null;
			if (sp.length == 1) {
				tableName = sp[0]
			} else {
				tableName = sp[1]
				catalogName = sp[0]
			}

			if (!existColumnsInDbCompletions) {
				syntaxCompletionItems = await queryTableFieldList(tableName, catalogName);
				existColumnsInDbCompletions = true
			}

		}
	}
	return [...syntaxCompletionItems, ...keywordsCompletionItems];
};


const queryCatalogList = async () => {
	let s = await dataSourceApi.queryCatalogList({
		id: currentInfo.id
	})
	if (s) {
		let d = []
		s.forEach((v) => {
			d.push({
				label: v,
				kind: languages.CompletionItemKind.Field,
				detail: 'catalog',
				sortText: '1' + v
			})
		})
		return d
	}
	return []
}


const querySchemaList = async (catalogName) => {
	var s = await dataSourceApi.querySchemaList({
		id: currentInfo.id
	})
	if (s) {
		var d = []
		s.forEach((v) => {
			d.push({
				label: v,
				kind: languages.CompletionItemKind.Field,
				detail: 'schema',
				sortText: '1' + v
			})
		})
		return d
	}
	return []
}


const queryTableList = async (catalogName) => {
	if (!catalogName) {
		return []
	}
	//查询表
	var s = await dataSourceApi.queryTableList({
		id: currentInfo.id, catalogName: catalogName.replace(/`/g, "")
	})

	//
// label: name,
// 	kind: monaco.languages.CompletionItemKind.Field,
// 	insertText: name
	if (s) {
		var d = []
		s.forEach((v) => {
			d.push({
				label: v,
				kind: languages.CompletionItemKind.Field,
				detail: 'table',
				sortText: '1' + v
			})
		})
		return d
	}
	return []
}


const queryTableFieldList = async (tableName, catalogName) => {
	//查询表
	let s = await dataSourceApi.queryTableFieldList({
		id: currentInfo.id,
		catalogName: catalogName.replace(/`/g, ""),
		tableName: tableName.replace(/`/g, "")
	})
	if (s) {
		let d = []
		s.forEach((v) => {
			d.push({
				label: v.columnName,
				kind: languages.CompletionItemKind.Field,
				detail: 'column',
				sortText: '1' + v.columnName
			})
		})
		return d
	}
	return []
}

setupLanguageFeatures(LanguageIdEnum.MYSQL, {
	completionItems: {
		enable: true, triggerCharacters: [' ', '.'], completionService,
	}
});
